package com.dattplace.controller;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;

import com.dattplace.cache.CacheFacade;
import com.dattplace.commons.Constants;
import com.dattplace.model.ResultCode;
import com.dattplace.model.ResultData;
import com.dattplace.model.User;
import com.dattplace.model.UserDeviceAccess;
import com.dattplace.service.IQiNiuService;
import com.dattplace.service.IShareService;
import com.dattplace.service.IUserService;
import com.dattplace.util.DESEncryption;
import com.dattplace.util.FileUploadUtil;
import com.dattplace.util.MD5Util;
import com.dattplace.util.PropertiesUtil;
import com.dattplace.util.RandomUtil;
import com.dattplace.util.RequestUtils;
import com.dattplace.util.StringUtil;
import com.dattplace.util.FileUploadUtil.UploadFileItem;
import com.dattplace.util.ImageUtil;
import com.dattplace.vo.SimpleModelVo;
import com.dattplace.vo.UserVo;

import net.coobird.thumbnailator.Thumbnails;


@Controller
@Path("/user")
public class UserController {

	@Autowired
	private Mapper mapper;

	@Autowired
	private IUserService userService;
	
	@Autowired
	private IShareService shareService;

	
    private final static CacheFacade cacheFacade = CacheFacade.getInstance();

	private static final Logger logger = Logger.getLogger(LoginController.class);

	private static final PropertiesUtil propertiesUtil = new PropertiesUtil("config.properties");

	@Autowired
	private IQiNiuService qiNiu;
	
	@POST
	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
	@Path("/updatePassword")
	public ResultData<Object> updatePassword(@FormParam("userId") final String userId,
			@FormParam("oldPassword") final String oldPassword, @FormParam("newpassword") final String newpassword,
			@Context final HttpServletRequest request) {

		ResultData<Object> resultData = new ResultData<Object>();

		UserVo user = userService.queryUserById(userId);

		String oldpsw = generalPassword(user.getUserName(), oldPassword);

		if (!oldpsw.equals(user.getPassword())) {
			resultData.setResCode(ResultCode.FAILTURE);
			resultData.setMsg("原始密码不正确");
			return resultData;
		}

		String newpsw = generalPassword(user.getUserName(), newpassword);
		userService.updatePassword(userId, newpsw);
		resultData.setResCode(ResultCode.SUCCESS);
		return resultData;
	}
	
	/**
     * 删除用户
     * @param userId
     * @param req
     */
    @Path("/{userId}/deleteUser")
    @GET
    public ResultData<Object> deleteUser(@PathParam("userId") final String userId,
            @Context HttpServletRequest req){
    	try{
    		userService.deleteUser(userId);
    		return ResultCode.success("删除用户成功", null);
    	}catch (Exception e) {
    		return ResultCode.error("删除用户失败", null);
		}
    }
    
    @Path("/saveUserPic")
	@POST
	public ResultData<Object> saveUserPic(@Context HttpServletRequest request) {
    	
    	String compress ="";
    	 try {
    		 
    		 String cropX =request.getParameter("cropX");
    		 String cropY =request.getParameter("cropY");
    		 String cropW =request.getParameter("cropW");
    		 String cropH =request.getParameter("cropH");
            	 
			 final UploadFileItem[] uploadFiles = FileUploadUtil.saveUploadFile(request);
			 if(uploadFiles.length==0){
				return ResultCode.error("上传文件不能为空", null);
			 }
			 File file = uploadFiles[0].getInternalFile();
		     String compressPicPath =propertiesUtil.getProperty("compressPicPath")+"/"+new Date().getTime()+".jpg";
		     
		     ImageUtil.cut(file.getPath(), compressPicPath, Integer.valueOf(cropX), Integer.valueOf(cropY), Integer.valueOf(cropW), Integer.valueOf(cropH), "jpg");
		 	 compress =qiNiu.upload(new File(compressPicPath));
			 return ResultCode.success("上传成功", compress);
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
    	return ResultCode.success("上传失败", compress);
    }
    
    
	
	/**
     * 后台使用
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @Path("/queryUserList")
    @GET
	public ResultData<Object> queryUserList(
			@QueryParam("pageNo") final int pageNo,
			@QueryParam("pageSize") final int pageSize,
			@QueryParam("keyWord") final String keyWord,
			@Context HttpServletRequest req) {
        
    	try{
    		
    		SimpleModelVo vo = new SimpleModelVo();
        	List<UserVo> list =userService.queryUserList(pageNo,pageSize,keyWord);
        	if(!CollectionUtils.isEmpty(list)){
        		for(UserVo userVo :list){
        			// 判断用户是否在线
        			Object obj =cacheFacade.get("showtimes_login", userVo.getUserId());
        			if(obj ==null){
        				userVo.setOnline(false);
        			}
        			else{
        				userVo.setOnline(true);
        			}
        		}
        	}
        	vo.setOnlineCount(Integer.valueOf(String.valueOf(cacheFacade.hahLength("showtimes_login"))));
            vo.setUserList(list);
            vo.setCount(userService.queryAllUserCount(keyWord));
    		return ResultCode.success("获取用户成功", vo);
    	}catch (Exception e) {
    		return ResultCode.error("获取用户失败", null);
		}
    }
    
    
    /**
     * 后台增加用户
     * @param userVo
     * @param req
     * @return
     */
     @Path("/saveUser")
     @POST
     public ResultData<Object> saveUser(final UserVo userVo,@Context HttpServletRequest req){
    	try{
    		
    		 if(StringUtil.isEmptyString(userVo.getUserName()) || StringUtil.isEmptyString(userVo.getNickName()) || StringUtil.isEmptyString(userVo.getPassword())){
    			return ResultCode.error("用户信息不能为空，新增失败", null);
    		 }
    		 User u =userService.queryUserByName(userVo.getUserName().trim());
    		 if(u!=null){
     			return ResultCode.error("该用户名已经存在", null);
    		 }
    		 userVo.setCreateDate(new Date());
        	 userVo.setUserId(new RandomUtil().getRandomId());
     		String psw = generalPassword(userVo.getUserName(), userVo.getPassword());

        	 userVo.setPassword(psw);
        	 userVo.setAccountStatus(1);
        	 return userService.register(mapper.map(userVo, User.class));
    	}catch (Exception e) {
    		return ResultCode.error("新增用户失败", null);
		}
     }
    
    /**
     * 更新用户状态
     * @param userId 用户ID
     * @param status 账号状态 0：正常 1：停用
     * @param req
     */
    @Path("/updateStatus")
    @GET
    public void updateStatus(@QueryParam("userId") final String userId,
    		@QueryParam("status") final int status,
            @Context HttpServletRequest req){
    	Map<String, Object> map = new HashMap<String, Object>();
    	map.put("accountStatus", status);
    	userService.updateUserByUserId(userId, map);
    }

	/**
	 * 注册用户
	 * 
	 * @param userVo
	 * @param request
	 * @return
	 * @throws IOException
	 * @throws Exception
	 */
	@Path("/register")
	@POST
	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
	public ResultData<Object> register(final UserVo userVo, @Context HttpServletRequest request)
			throws IOException, Exception {

		ResultData<Object> resultData = new ResultData<Object>();
		// 参数验证
		if (StringUtil.isEmptyString(userVo.getMobile())
				|| StringUtil.isEmptyString(userVo.getDeveiceId())) {
			resultData.setMsg("请求参数为空，请检查参数。");
			resultData.setResCode(ResultCode.FAILTURE);
			return resultData;
		}

		// 手机号注册
		User u = userService.queryUserByPhone(userVo.getMobile());
		if (u != null) {
			resultData.setMsg("该手机号已经被注册，请从新输入。");
			resultData.setResCode(ResultCode.FAILTURE);
			return resultData;
		}
		// 返回结果
		UserVo resultVo = new UserVo();
		User user = new User();
		user.setUserId(new RandomUtil().getRandomId());

		String psw = generalPassword(userVo.getMobile(), userVo.getPassword());
		user.setPassword(psw);
		// 客户端类型 1:网页,2：Android ,3：IOS
		int clientFlag = getClientFlag(request);

		Date lastLoginTime = new Date();
		String accessToken = MD5Util.string2MD5(userVo.getMobile() + new Date().getTime());
		user.setAccessToken(accessToken);
		user.setExpireTime(7776000);
		user.setLastLoginTime(lastLoginTime);
		user.setOnline(false);
		UserDeviceAccess deviceAccess = new UserDeviceAccess();
		Map<Integer, UserDeviceAccess> userDevice = new HashMap<Integer, UserDeviceAccess>();
		deviceAccess.setDeviceId(userVo.getDeveiceId());
		deviceAccess.setClientFlag(clientFlag);
		deviceAccess.setLastLoginTime(lastLoginTime);
		userDevice.put(clientFlag, deviceAccess);
		user.setTokenTime(lastLoginTime);
		user.setCreateDate(lastLoginTime);
		userService.register(user);
		resultVo = mapper.map(user, UserVo.class);
		resultData.setResCode(ResultCode.SUCCESS);
		resultData.setObj(resultVo);
		return resultData;
	}

	/**
	 * 获取用户详情
	 * @param userId
	 * @param request
	 * @return
	 * @throws IOException
	 * @throws Exception
	 */
	@Path("/getUserDetailById/{userId}")
	@GET
	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
	public ResultData<Object> getUserDetailById(@PathParam("userId") final String userId,
			@Context final HttpServletRequest request) throws IOException, Exception {
		
		 ResultData<Object> resultData = new ResultData<Object>();
		 UserVo u =userService.queryUserById(userId);
		 if(u ==null){
			 resultData.setResCode(ResultCode.FAILTURE);
			 resultData.setMsg("用户不存在");
			 return resultData;
		 }
		 u.setShareCount(Integer.valueOf(String.valueOf(shareService.queryShareCount(u.getUserId()))));
		 resultData.setResCode(ResultCode.SUCCESS);
		 resultData.setObj(u);
		 return resultData;
	}

	
	/**
	 * 更新用户信息
	 * @param userVo
	 * @param req
	 * @return
	 */
	@Path("/updateUser")
    @POST
    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
    public ResultData<Object> updateUser(final UserVo userVo, @Context final HttpServletRequest req,
    	    @Context final HttpServletResponse resq) {

		ResultData<Object> result =new ResultData<>();

        Map<String,Object> property = new HashMap<String, Object>();
        final HttpSession session = req.getSession();
        if(StringUtil.isNotEmptyString(userVo.getUserPicUrl())){
            property.put("userPicUrl", userVo.getUserPicUrl());
        }
        
        if(StringUtil.isNotEmptyString(userVo.getNickName())){
            property.put("nickName", userVo.getNickName());
        }
        
        if(StringUtil.isNotEmptyString(userVo.getUserName())){
            property.put("userName", userVo.getUserName());
        }
        
        if(userVo.getUserType()>0){
            property.put("userType", userVo.getUserType());
        }
        if(userVo.getSex()>0){
            property.put("sex", userVo.getSex());
        }
        
        if(StringUtil.isNotEmptyString(userVo.getBirthDate())){
            property.put("birthDate", userVo.getBirthDate());
        }
        
        userService.updateUserProperty(userVo.getUserId(), property);
        UserVo userVo1 =userService.queryUserById(userVo.getUserId());
        
        if(userVo1 !=null){
        	User user =mapper.map(userVo1, User.class);
        	result.setObj(userVo1);
        	// 更新缓存
            session.setAttribute(Constants.LOGIN_SESSION_KEY, user);
        }
        result.setResCode(ResultCode.SUCCESS);
        return result;
    }
	
	
	/**
	 * 生成加密密码 手机号加密
	 * 
	 * @param mobile
	 * @param password
	 * @return
	 */
	private String generalPassword(final String userName, final String password) {
		String decryptStr = "";
		try {
			decryptStr = DESEncryption.decrypt(password, userName);
		} catch (IOException e) {
			logger.error("Error in decrypt. Reason: " + e.getMessage());
		} catch (Exception e) {
			logger.error("Error in decrypt. Reason: " + e.getMessage());
		}

		if (userName.indexOf("@") != -1) {
			String shortUserName = userName.substring(0, userName.indexOf("@"));
			return MD5Util.string2MD5(shortUserName.toLowerCase() + Constants.USER_KEY + MD5Util.string2MD5(decryptStr));
		} else {
			return MD5Util.string2MD5(userName.toLowerCase() + Constants.USER_KEY + MD5Util.string2MD5(decryptStr));
		}
	}
	
	/**
	 * 获取客户端类型
	 * 
	 * @param request
	 * @return
	 */
	private int getClientFlag(HttpServletRequest request) {
		return RequestUtils.getClientFlag(request);
	}
}
